<?php

namespace App\Exceptions;

use Exception;
use Symfony\Component\HttpKernel\Exception\GoneHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\Exception\ConflictHttpException;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\NotAcceptableHttpException;
use Symfony\Component\HttpKernel\Exception\LengthRequiredHttpException;
use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException;
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
use Symfony\Component\HttpKernel\Exception\PreconditionFailedHttpException;
use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException;
use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;
use Symfony\Component\HttpKernel\Exception\PreconditionRequiredHttpException;
use Symfony\Component\HttpKernel\Exception\UnsupportedMediaTypeHttpException;

class ExceptionHelper
{
    const SUCCESS_CODE = 200;   // 操作成功

    const USER_NOT_LOGIN         = 20001; // 用户未登录
    const USER_LOGIN_FAILED      = 20002; // 用户未注册
    const USER_IS_LOCK           = 20003; // 手机号已被冻结，请联系管理员
    const PERMISSION_DENIED      = 20004; // 无权操作
    const USER_NO_MOBILE         = 20005; // 用户未绑定手机号
    const PLACE_UPLOAD_IMAGE     = 20006; // 请上传图片文件
    const PLACE_UPLOAD_RADIO     = 20007; // 请上传视频文件
    const PLACE_UPLOAD_AUDIO     = 20008; // 请上传音频文件
    const PLEASE_UPLOAD_FILE     = 20051; // 请上传文件
    const USER_LOGIN_PASSWORD    = 20009; // 密码错误
    const DEFAULT_ERROR          = 20010; // 普通错误信息
    const MOBILE_IS_EXITS        = 20011; // 手机号已存在
    const MOBILE_NOT_EXITS       = 20012; // 手机号未注册
    const BALANCE_NOT_ENOUGH     = 20013; // 余额不足
    const USER_LOGIN_OTHER       = 20014; // 账号已在其他地方登录
    const USER_LOGIN_EXPIRE      = 20015; // 登录超时
    const ADMIN_LOGIN_FAILED     = 20016; // 用户名或密码错误
    const MOBILE_NOT_RIGHT       = 20017; // 手机号与当前用户不匹配
    const PRODUCT_IS_DELETE      = 20018; // 商品已下架或已删除
    const PRODUCT_IS_ENOUGH      = 20019; // 库存不足
    const BUY_NUMBER_NOT_ZERO    = 20020; // 购买数量不能小于1
    const USER_CANT_GROUP        = 20021; // 您参与过此次拼团，无法再次参与
    const SMS_SEND_FAILED        = 20022; // 短信验证码发送失败
    const INTEGRAL_NOT_ENOUGH    = 20023; // 积分余额不足
    const ID_CARD_FORMAT_ERR     = 20024; // 身份证号码格式错误
    const INVALID_ACTION         = 20025; // 不允许的操作
    const USER_MAST_BIND         = 20026; // 请绑定手机后操作
    const PLACE_UPLOAD_VIDEO     = 20027; // 请上传音频文件
    const GOO_DE_ERROR           = 20050; // 高德解析失败
    const IMAGE_INVALID          = 20052; // 高德解析失败
    const REFERRER_UID_INVALID   = 20053; // 推荐码无效
    const USER_NOT_CERTIFY       = 20054; // 未实名认证状态码
    const USER_VIP_LIMIT         = 20055; // 非VIP不可操作
    const USER_OPERATE_NUM_LIMIT = 20056; // 数量限制

    const INVALID_CHANNEL     = 40001; // 无效的渠道
    const SIGN_ERROR          = 40002; // 签名错误
    const INVALID_REQUEST     = 40003; // 无效的请求
    const REQUEST_TOO_MANY    = 40004; // 请求过于频繁，请稍后再试
    const IP_NOT_ALLOWED      = 40000; // IP不被允许
    const HTTP_NOT_FOUND      = 40400; // 页面未找到
    const OBJECT_NOT_FOUND    = 40403; // 对象不存在
    const SMS_CODE_OVER_LIMIT = 40301; // 短信发送次数过多，请明日再试
    const PARAMS_ERROR        = 41701; // 参数错误
    const PARAMS_NOT_RIGHT    = 42201; // 请求参数不正确
    const NOT_SUPPORT_PARAM   = 42202; // 不支持的参数
    const NOT_SUPPORT_ACT     = 42203; // 不允许的操作

    const SYSTEM_ERROR       = 50000; // 系统繁忙，请稍后再试！
    const DATABASE_ERROR     = 50001; // 数据库错误
    const TABLE_NO_CHANGE    = 50002; // 表更新失败
    const TABLE_CREATE_ERROR = 50003; // 表创建失败
    const CONFIG_DISABLED    = 50004; // 配置项不存在
    const RETRY_TOO_MUCH     = 50005; // 队列重试次数达到上限

    const ADD_FAILURE  = 60004;
    const EDIT_FAILURE = 60005;

    const RETRY_AFTER = 5;

    public static $msg = [
        self::SUCCESS_CODE           => '操作成功',
        self::USER_NOT_LOGIN         => '用户未登录',
        self::USER_NO_MOBILE         => '未绑定手机号',
        self::USER_LOGIN_FAILED      => '用户未注册',
        self::USER_LOGIN_PASSWORD    => '密码错误',
        self::PERMISSION_DENIED      => '无权操作',
        self::USER_IS_LOCK           => '手机号已被冻结，请联系管理员',
        self::INVALID_CHANNEL        => '无效的渠道',
        self::SIGN_ERROR             => '签名错误',
        self::INVALID_REQUEST        => '无效的请求',
        self::REQUEST_TOO_MANY       => '请求过于频繁，请稍后再试',
        self::IP_NOT_ALLOWED         => 'IP未被允许',
        self::OBJECT_NOT_FOUND       => '对象不存在',
        self::PARAMS_ERROR           => '请求参数错误',
        self::PLACE_UPLOAD_IMAGE     => '请上传图片文件',
        self::PLACE_UPLOAD_RADIO     => '请上传视频文件',
        self::PLACE_UPLOAD_AUDIO     => '请上传音频文件',
        self::PLEASE_UPLOAD_FILE     => '请上传文件',
        self::DATABASE_ERROR         => '服务器开小差了，请稍后重试',
        self::SYSTEM_ERROR           => '系统繁忙，请稍后再试！',
        self::TABLE_NO_CHANGE        => '表更新失败',
        self::TABLE_CREATE_ERROR     => '表创建失败',
        self::NOT_SUPPORT_PARAM      => '不支持的参数',
        self::SMS_CODE_OVER_LIMIT    => '短信发送次数过多，请明日再试',
        self::MOBILE_IS_EXITS        => '手机号已被注册',
        self::MOBILE_NOT_EXITS       => '手机号不存在',
        self::USER_LOGIN_OTHER       => '账号已在其他地方登录',
        self::USER_LOGIN_EXPIRE      => '登录超时，请重新登录',
        self::ADMIN_LOGIN_FAILED     => '用户名或密码错误',
        self::MOBILE_NOT_RIGHT       => '手机号与当前用户不匹配',
        self::CONFIG_DISABLED        => '配置项不存在',
        self::BALANCE_NOT_ENOUGH     => '虚拟币余额不足',
        self::PARAMS_NOT_RIGHT       => '请求参数不正确',
        self::RETRY_TOO_MUCH         => '队列重试次数达到上限',
        self::NOT_SUPPORT_ACT        => '不允许的操作',
        self::HTTP_NOT_FOUND         => '页面不存在',
        self::PRODUCT_IS_DELETE      => '商品已下架或已删除',
        self::PRODUCT_IS_ENOUGH      => '库存不足',
        self::BUY_NUMBER_NOT_ZERO    => '购买数量不能小于1',
        self::USER_CANT_GROUP        => '您参与过此次拼团，无法再次参与',
        self::SMS_SEND_FAILED        => '短信验证码发送失败',
        self::INTEGRAL_NOT_ENOUGH    => '积分余额不足',
        self::ID_CARD_FORMAT_ERR     => '身份证号码格式错误',
        self::INVALID_ACTION         => '不允许的操作',
        self::USER_MAST_BIND         => '您还未绑定手机，请绑定手机后操作',
        self::PLACE_UPLOAD_VIDEO     => '请上传视频文件',
        self::ADD_FAILURE            => "添加失败",
        self::EDIT_FAILURE           => "修改失败",
        self::IMAGE_INVALID          => "未检测到合格人像",
        self::REFERRER_UID_INVALID   => '推荐人ID无效',
        self::DEFAULT_ERROR          => '操作失败',
        self::USER_NOT_CERTIFY       => '您的账号未实名认证，请前往认证',
        self::USER_VIP_LIMIT         => '您的账号未购买VIP，请前往购买',
        self::USER_OPERATE_NUM_LIMIT => '您的账号数量不够，请前往购买',
    ];

    public static function getMsg($code, $message = "")
    {
        if (!$message && isset(self::$msg[$code])) {
            return self::$msg[$code];
        } elseif ($message) {
            return $message;
        } else {
            return '未知错误';
        }
    }

    public static function getInstance($code, $message = "", $data = [], Exception $previous = null)
    {
        $status  = self::getStaticByCode($code);
        $message = self::getMsg($code, $message);
        switch ($status) {
            case 400:
                $e = new BadRequestHttpException($message, $previous, $code);
                break;
            case 403:
                $e = new AccessDeniedHttpException($message, $previous, $code);
                break;
            case 404:
                $e = new NotFoundHttpException($message, $previous, $code);
                break;
            case 405:
                $e = new MethodNotAllowedHttpException([], $message, $previous, $code);
                break;
            case 406:
                $e = new NotAcceptableHttpException($message, $previous, $code);
                break;
            case 409:
                $e = new ConflictHttpException($message, $previous, $code);
                break;
            case 410:
                $e = new GoneHttpException($message, $previous, $code);
                break;
            case 411:
                $e = new LengthRequiredHttpException($message, $previous, $code);
                break;
            case 412:
                $e = new PreconditionFailedHttpException($message, $previous, $code);
                break;
            case 415:
                $e = new UnsupportedMediaTypeHttpException($message, $previous, $code);
                break;
            case 417:
                $e = new QueryStringException($message, $previous, $code);
                break;
            case 422:
                $e = new UnprocessableEntityHttpException($message, $previous, $code);
                break;
            case 428:
                $e = new PreconditionRequiredHttpException($message, $previous, $code);
                break;
            case 429:
                $e = new TooManyRequestsHttpException(self::RETRY_AFTER, $message, $previous, $code);
                break;
            case 500:
                $e = new SystemException($message, $code, $previous);
                break;
            case 503:
                $e = new ServiceUnavailableHttpException(self::RETRY_AFTER, $message, $previous, $code);
                break;
            default:
                $e = new UndefinedException($message, $code, $previous);
        }
        $e->data = $data;

        return $e;
    }

    public static function getStaticByCode($code)
    {
        return substr($code, 0, 3);
    }
}
